home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Languages / PowerMacOberon 1.2 / Source / Elems / IndexElems.Mod (.txt) < prev    next >
Oberon Text  |  1995-08-22  |  11KB  |  320 lines

  1. Syntax10.Scn.Fnt
  2. StampElems
  3. Alloc
  4. 10 Aug 95
  5. Syntax10b.Scn.Fnt
  6. Syntax10m.Scn.Fnt
  7. MODULE IndexElems;    (* mah  
  8.     IMPORT
  9.         Display, Input, Files, Fonts, Printer, Oberon, Texts, Viewers, MenuViewers, TextFrames, TextPrinter, MarkElems, LinkElems;
  10.     CONST
  11.         middleKey = 1;
  12.         Height = 8*TextFrames.Unit;
  13.         Width = 13*TextFrames.Unit;
  14.     TYPE
  15.         Elem* = POINTER TO ElemDesc;
  16.         ElemDesc* = RECORD(MarkElems.ElemDesc)
  17.             text*: Texts.Text;
  18.             visible, empty: BOOLEAN;
  19.             pno-: INTEGER;
  20.             next: Elem;
  21.         END;
  22.     EditFrame = POINTER TO EditFrameDesc;
  23.     EditFrameDesc = RECORD (TextFrames.FrameDesc)
  24.         elem: Elem
  25.     END;
  26.         w: Texts.Writer;
  27.         elems: Elem;
  28.         icon, invIcon: Display.Pattern; (* x = 0, y = -curfnt.minY, w = 13, h = 8 *)
  29.     PROCEDURE GetDsr (f: Display.Frame; pos: LONGINT; fnt: Fonts.Font; VAR dsr: INTEGER);
  30.         VAR p: TextFrames.Parc; beg: LONGINT;
  31.     BEGIN
  32.         IF f = NIL THEN
  33.             IF fnt = NIL THEN dsr := 0 ELSE dsr := - fnt.minY END
  34.         ELSE
  35.             TextFrames.ParcBefore(f(TextFrames.Frame).text, pos, p, beg);
  36.             dsr := SHORT(p.dsr DIV TextFrames.Unit)
  37.         END
  38.     END GetDsr;
  39.     PROCEDURE CopyText (T: Texts.Text): Texts.Text;
  40.         VAR t: Texts.Text; buf: Texts.Buffer;
  41.     BEGIN
  42.         NEW(buf); Texts.OpenBuf(buf); Texts.Save(T, 0, T.len, buf);
  43.         t := TextFrames.Text(""); Texts.Append(t, buf); RETURN t
  44.     END CopyText;
  45.     PROCEDURE HandleEdit (F: Display.Frame; VAR M: Display.FrameMsg);    
  46.         VAR F1: EditFrame;
  47.     BEGIN
  48.         TextFrames.Handle (F, M);
  49.         WITH F: EditFrame DO
  50.             IF M IS Oberon.CopyMsg THEN
  51.                 NEW(F1); TextFrames.Open(F1, F.text, F.org);
  52.                 F1.handle := F.handle; F1.elem := F.elem; M(Oberon.CopyMsg).F := F1
  53.             END
  54.         END
  55.     END HandleEdit;
  56.     PROCEDURE OpenEditor (E: Elem);
  57.         VAR V: Viewers.Viewer; F: EditFrame; x, y: INTEGER;  
  58.     BEGIN
  59.         IF E.empty THEN E.text := TextFrames.Text ("") END;
  60.         Oberon.AllocateUserViewer (Oberon.Mouse.X, x, y);
  61.         NEW(F); F.elem := E; TextFrames.Open (F, CopyText(E.text), 0); F.handle := HandleEdit;
  62.         V := MenuViewers.New (TextFrames.NewMenu("Index Entry",
  63.                 "System.Close  System.Copy  System.Grow  IndexElems.Update "),
  64.                 F, TextFrames.menuH, x, y)
  65.     END OpenEditor;
  66.     PROCEDURE MarkedFrame (VAR name: ARRAY OF CHAR): TextFrames.Frame;
  67.         VAR V: Viewers.Viewer; S: Texts.Scanner;
  68.     BEGIN V := Oberon.MarkedViewer ();
  69.         IF (V#NIL) & (V IS MenuViewers.Viewer) & (V.dsc.next IS TextFrames.Frame) THEN
  70.             Texts.OpenScanner(S, V.dsc(TextFrames.Frame).text, 0); Texts.Scan(S);
  71.             COPY( S.s, name); RETURN V.dsc.next(TextFrames.Frame)
  72.         ELSE RETURN NIL
  73.         END
  74.     END MarkedFrame;
  75.     PROCEDURE Copy (SE, DE: Elem);
  76.     BEGIN
  77.         Texts.CopyElem(SE, DE); DE.key := SE.key;
  78.         DE.visible := TRUE; DE.text := CopyText (SE.text)
  79.     END Copy;
  80.     PROCEDURE Edit (E: Elem; x0, y0, dsr: INTEGER; keysum: SET);
  81.         VAR w, h, x, y: INTEGER; keys: SET;
  82.     BEGIN
  83.         IF keysum = {middleKey} THEN
  84.             w := SHORT (E.W DIV TextFrames.Unit); h := SHORT (E.H DIV TextFrames.Unit);
  85.             Oberon.RemoveMarks (x0, y0, w, h);
  86.             Display.CopyPattern(Display.white, icon, x0, y0 + dsr, Display.invert);
  87.             Display.CopyPattern(Display.white, invIcon, x0, y0 + dsr, Display.invert);
  88.             REPEAT Input.Mouse (keys, x, y); keysum := keysum + keys;
  89.                 Oberon.DrawCursor (Oberon.Mouse, Oberon.Arrow, x, y);
  90.             UNTIL keys = {};
  91.             Display.CopyPattern(Display.white, invIcon, x0, y0 + dsr, Display.invert);
  92.             Display.CopyPattern(Display.white, icon, x0, y0+ dsr, Display.invert);
  93.             IF keysum = {middleKey} THEN OpenEditor (E) END
  94.         END
  95.     END Edit;
  96.     PROCEDURE Handle* (E: Texts.Elem; VAR msg: Texts.ElemMsg);
  97.         VAR e: Elem; pos: LONGINT; w, h, dsr: INTEGER; keys, keysum: SET;
  98.     BEGIN
  99.         WITH E: Elem DO
  100.             WITH msg : TextFrames.DisplayMsg DO
  101.                 WITH msg: TextFrames.DisplayMsg DO
  102.                     IF ~msg.prepare THEN 
  103.                         GetDsr (msg.frame, msg.pos, msg.fnt, dsr);
  104.                         IF E.visible THEN Display.CopyPattern(Display.white, icon, msg.X0, msg.Y0 + dsr, Display.paint) END
  105.                     ELSE
  106.                         GetDsr (msg.frame, msg.pos, msg.fnt, msg.Y0); E.W := Width;
  107.                         IF E.visible THEN E.H := 8 * TextFrames.Unit ELSE E.H := 0 END
  108.                     END
  109.                 END
  110.             | msg : Texts.IdentifyMsg DO
  111.                 msg.mod:="IndexElems"; msg.proc:="Alloc"
  112.             | msg : Texts.CopyMsg DO
  113.                 NEW(e); Copy (E, e); msg(Texts.CopyMsg).e := e;
  114.             | msg : TextFrames.TrackMsg DO
  115.                 GetDsr (msg.frame, msg.pos, msg.fnt, dsr);
  116.                 Edit(E, msg.X0, msg.Y0, dsr, msg.keys)
  117.             | msg : Texts.FileMsg DO
  118.                 IF msg.id = Texts.load THEN
  119.                     Files.ReadBool (msg.r, E.visible); Files.ReadBool (msg.r, E.empty);
  120.                     E.text := TextFrames.Text (""); Texts.Load (msg.r, E.text)
  121.                 ELSIF msg.id = Texts.store THEN
  122.                     Files.WriteBool (msg.r, E.visible); Files.WriteBool (msg.r, E.empty);
  123.                     Texts.Store (msg.r, E.text)
  124.                 END
  125.             | msg : TextPrinter.PrintMsg DO
  126.                 IF msg.prepare THEN E(Elem).pno := msg.pno; E.W := 0 END
  127.             ELSE
  128.             END
  129.         END
  130.     END Handle;
  131.     PROCEDURE Alloc*;
  132.         VAR e: Elem;
  133.     BEGIN NEW(e); e.handle:=Handle; Texts.new:=e
  134.     END Alloc;
  135.     PROCEDURE Insert*;
  136.         e: Elem; insert: TextFrames.InsertElemMsg;
  137.         t: Texts.Text; buf: Texts.Buffer; start, end, time: LONGINT;
  138.     BEGIN
  139.         Oberon.GetSelection(t, start, end, time);
  140.         NEW (e); e.text := TextFrames.Text ("");
  141.         e.handle := Handle; e.visible := TRUE; e.key := Oberon.Time ();
  142.         e.H := Height; e.W := Width;
  143.         IF time >= 0 THEN
  144.             NEW(buf); Texts.OpenBuf(buf);
  145.             Texts.Save(t, start, end, buf); Texts.Append(e.text, buf)
  146.         ELSE e.empty := TRUE
  147.         END;
  148.         insert.e := e; Viewers.Broadcast (insert)
  149.     END Insert;
  150.     PROCEDURE Hide*;
  151.     VAR f: TextFrames.Frame; pos: LONGINT; r: Texts.Reader; name: ARRAY 256 OF CHAR;
  152.     BEGIN
  153.         f := MarkedFrame (name); 
  154.         Texts.OpenReader (r, f.text, 0); Texts.ReadElem (r);
  155.         WHILE ~r.eot DO
  156.             IF r.elem IS Elem THEN
  157.                 r.elem(Elem).visible := FALSE; pos := Texts.ElemPos (r.elem); r.elem.W := 0;
  158.                 TextFrames.NotifyDisplay(f.text, Texts.replace, pos, pos+1)
  159.              END;
  160.             Texts.ReadElem (r)
  161.         END        
  162.     END Hide;
  163.     PROCEDURE Show*;
  164.     VAR f: TextFrames.Frame; pos: LONGINT; r: Texts.Reader; name: ARRAY 256 OF CHAR;
  165.     BEGIN
  166.         f := MarkedFrame (name);
  167.         Texts.OpenReader (r, f.text, 0); Texts.ReadElem (r);
  168.         WHILE ~r.eot DO
  169.             IF r.elem IS Elem THEN
  170.                 r.elem(Elem).visible := TRUE; pos := Texts.ElemPos (r.elem);
  171.                 r.elem.W := Width;
  172.                 TextFrames.NotifyDisplay(f.text, Texts.replace, pos, pos+1)
  173.             END;
  174.             Texts.ReadElem (r)
  175.         END        
  176.     END Show;
  177.     PROCEDURE Update*;
  178.         VAR f: EditFrame; s: Texts.Scanner; menuText, text: Texts.Text; e: Elem; pos: LONGINT;
  179.     BEGIN
  180.         IF Oberon.Par.frame = Oberon.Par.vwr.dsc THEN
  181.             f := Oberon.Par.frame.next(EditFrame); e := f.elem;
  182.             IF f.text.len # 0 THEN e.text := CopyText(f.text); e.empty := FALSE ELSE e.empty := TRUE END;
  183.             menuText := Oberon.Par.frame(TextFrames.Frame).text;
  184.             Texts.OpenReader (s, menuText, menuText.len-1); Texts.Read (s, s.c);
  185.             IF s.c = "!" THEN Texts.Delete (menuText, menuText.len-1, menuText.len) END
  186.         END
  187.     END Update;
  188.     PROCEDURE CharDiff (c1, c2: CHAR) : INTEGER;
  189.     BEGIN
  190.         IF (c1 = '
  191. ') OR (c1 = '
  192. ') THEN c1 := 'o' END;
  193.         IF (c1 = '
  194. ') OR (c1 = '
  195. ') THEN c1 := 'u' END;
  196.         IF (c1 = '
  197. ') OR (c1 = '
  198. ') THEN c1 := 'a' END;
  199.         IF (c2 = '
  200. ') OR (c2 = '
  201. ') THEN c2 := 'o' END;
  202.         IF (c2 = '
  203. ') OR (c2 = '
  204. ') THEN c2 := 'u' END;
  205.         IF (c2 = '
  206. ') OR (c2 = '
  207. ') THEN c2 := 'a' END;
  208.         RETURN ORD (CAP (c1)) - ORD (CAP (c2))
  209.     END CharDiff;
  210.     PROCEDURE CompareTexts (t1, t2: Texts.Text) : INTEGER;   (* t1-t2 *)
  211.     VAR r1, r2: Texts.Reader; ch1, ch2: CHAR; diff: INTEGER;
  212.     BEGIN
  213.         Texts.OpenReader(r1, t1, 0); Texts.OpenReader(r2, t2, 0);
  214.         REPEAT Texts.Read (r1, ch1); Texts.Read (r2, ch2); diff := CharDiff (ch1, ch2);
  215.         UNTIL r1.eot OR r2.eot OR (diff # 0);
  216.         IF r1.eot & r2.eot THEN RETURN 0
  217.         ELSIF r1.eot THEN RETURN -1
  218.         ELSIF r2.eot THEN RETURN 1
  219.         ELSE RETURN diff
  220.         END
  221.     END CompareTexts;
  222.     PROCEDURE Sort;
  223.         VAR e, sb, s, sorted: Elem;
  224.     BEGIN
  225.         sorted := elems;
  226.         elems := elems.next;
  227.         sorted.next := NIL;
  228.         WHILE elems # NIL DO
  229.             e := elems; elems := elems.next;
  230.             IF CompareTexts (sorted.text, e.text) >= 0 THEN e.next := sorted; sorted := e
  231.             ELSE
  232.                 sb := sorted; s:= sorted.next;
  233.                 WHILE (s # NIL) & (CompareTexts (s.text, e.text) < 0) DO
  234.                     sb := s; s := s.next
  235.                 END;
  236.                 e.next := sb.next; sb.next := e
  237.             END
  238.         END;
  239.         elems := sorted
  240.     END Sort;    
  241.     PROCEDURE BuildText (e: Elem; t: Texts.Text; pos: LONGINT);
  242.     VAR s: Texts.Scanner;
  243.     BEGIN
  244.         e.text := TextFrames.Text ("");
  245.         Texts.OpenScanner (s, t, pos+1); Texts.Scan (s);
  246.         IF (s.class = Texts.String) OR (s.class = Texts.Name) THEN
  247.             Texts.WriteString (w, s.s); Texts.Append (e.text, w.buf)
  248.         END
  249.     END BuildText;    
  250.     PROCEDURE Index*;
  251.         V : Viewers.Viewer;
  252.         res, X, Y : INTEGER;
  253.         text: Texts.Text;
  254.         f: TextFrames.Frame;
  255.         r: Texts.Reader;
  256.         buf: Texts.Buffer;
  257.         e, ee: Elem;
  258.         name: ARRAY 256 OF CHAR;
  259.     BEGIN
  260.         f := MarkedFrame (name);
  261.         text := TextFrames.Text ("");
  262.         Oberon.Call ("Edit.Print", Oberon.Par, FALSE, res);
  263.         Texts.OpenReader(r, f.text, 0); Texts.ReadElem(r);
  264.         WHILE ~ r.eot DO
  265.             IF r.elem IS Elem THEN
  266.                 IF r.elem(Elem).empty THEN BuildText (r.elem(Elem), f.text, Texts.ElemPos (r.elem)) END;
  267.                 r.elem(Elem).next := elems; elems := r.elem(Elem)
  268.             END;
  269.             Texts.ReadElem(r)
  270.         END;
  271.         Sort (); e:=elems;
  272.         WHILE e # NIL DO
  273.             NEW(buf); Texts.OpenBuf(buf);
  274.             Texts.Save(e.text, 0, e.text.len, buf); Texts.Append (text, buf);
  275.             Texts.Write (w, 9X); Texts.WriteInt (w, e.pno, 0); 
  276.             Texts.WriteElem (w, LinkElems.New (name, e.key));
  277.             WHILE (e.next # NIL) & (CompareTexts (e.text, e.next.text) = 0) DO
  278.                 IF e.pno # e.next.pno THEN
  279.                     Texts.WriteString (w, ", "); Texts.WriteInt (w, e.next.pno, 0)
  280.                 END;
  281.                 Texts.WriteElem (w, LinkElems.New (name, e.next.key));
  282.                 e := e.next
  283.             END;
  284.             Texts.WriteLn (w);
  285.             Texts.Append (text, w.buf);
  286.             e := e.next
  287.         END;
  288.         e := elems; WHILE e # NIL DO ee := e.next; e.next := NIL; e := ee END; elems := NIL;
  289.         Oberon.AllocateUserViewer (0, X, Y);
  290.         V := MenuViewers.New (
  291.             TextFrames.NewMenu ("IndexElems.Index", "^Edit.Menu.Text"),
  292.             TextFrames.NewText (text, 0),
  293.             TextFrames.menuH,
  294.             X, Y)
  295.     END Index;
  296. PROCEDURE InitIcon;
  297.     VAR line: ARRAY 9 OF SET;
  298. BEGIN
  299.     line[1] := {4..8};
  300.     line[2] := {3, 9};
  301.     line[3] := {2, 5..7, 10};
  302.     line[4] := {2, 6, 10};
  303.     line[5] := {2, 6, 10};
  304.     line[6] := {2, 5..7, 10};
  305.     line[7] := {3, 9};
  306.     line[8] := {4..8};
  307.     icon := Display.NewPattern(line, 13, 8);
  308.     line[1] := {4..8};
  309.     line[2] := {3..9};
  310.     line[3] := {2..4, 8..10};
  311.     line[4] := {2..5, 7..10};
  312.     line[5] := {2..5, 7..10};
  313.     line[6] := {2..4, 8..10};
  314.     line[7] := {3..9};
  315.     line[8] := {4..8};
  316.     invIcon := Display.NewPattern(line, 13, 8)
  317. END InitIcon;
  318. BEGIN Texts.OpenWriter (w); InitIcon
  319. END IndexElems.
  320.